package platform.app;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import common.socket.AbstractTCP;
import common.socket.CmdMessageGrpIds;
import common.socket.TCP;
import common.socket.UDP;
import common.struct.*;
import common.struct.ConstantEnum.SensorMode;
import common.struct.SensorInfo;
import common.struct.ServiceInfo;
import common.struct.sync.SynchronousString;
import platform.Platform;
import platform.pubsub.Channel;
import platform.resource.ActorMgr;
import platform.resource.ResMgrThread;
import platform.resource.SensorMgr;
import platform.pubsub.AbstractSubscriber;
import platform.pubsub.Publisher;
import common.struct.ConstantEnum.CmdType;
import common.struct.ConstantEnum.ServiceType;
import platform.database.Condition;
import platform.database.Order;
import platform.service.inv.AppInvServer;
import platform.service.inv.PlatformInvServer;

import java.io.IOException;
import java.net.Socket;
import java.util.*;

public class AppDriver extends AbstractSubscriber implements Runnable {
    private TCP tcp;
    private String clientIP = null;
    private int clientUDPPort = -1;
    private int grpId = -1;
    private boolean getMsgThreadState = false;
    private AppMgr appMgr = null;
    private final SynchronousString _getSensorData = new SynchronousString();
//    private final SynchronousSensorData _invGetSensorData = new SynchronousSensorData();
    private final SynchronousString _setActorCmd = new SynchronousString();

    public AppDriver(Socket socket) {
        this.tcp = new AppDriverTCP(socket, false);
    }

    public String getClientIP() {
        return clientIP;
    }

    public int getClientUDPPort() {
        return clientUDPPort;
    }

    public class AppDriverTCP extends AbstractTCP {
        public AppDriverTCP(Socket socket, boolean lockFlag) {
            super(socket, lockFlag);
        }

        public AppDriverTCP(Socket socket) {
            super(socket);
        }

        @Override
        public void close() {
            try {
                socket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            disConnectPlatform();
        }

        @Override
        public void callback() {
            String name = "AppDriver";
            if (appMgr != null) {
                name = appMgr.getAppName();
            }
            logger.error(String.format("[%s]: TCP connection is broken. Start releasing app resources...", name));
            if (disConnectPlatform().equals("{\"state\":true}")) {
                logger.info(String.format("[%s]: App resource released successfully.", name));
            } else {
                logger.error(String.format("[%s]: App resource released failed.", name));
            }
        }
    }

    @Override
    public void onMessage(String channel, String msg) {
//        logger.info(String.format("appDriver onmessage: %s, %s", channel, msg));
        String flag = appMgr.getRequestMap().get(channel).nonBlockTake();
//        logger.info(flag);
        if (flag.equalsIgnoreCase("getSensorData")) {
            _getSensorData.put(msg);
        } else if (flag.equalsIgnoreCase("invGetSensorData")) {
            appMgr.getInvServer().getInvGetSensorData().put(SensorData.fromJSONString(msg));
        } else if (flag.equalsIgnoreCase("passiveGetSensorData")) {
            JSONObject jo = new JSONObject(2);
            jo.put("channel", channel);
            jo.put("msg", msg);
            UDP.send(clientIP, clientUDPPort, jo.toJSONString());
            logger.info(String.format("[Platform -> %s][UDP]: %s", appMgr.getAppName(), jo.toJSONString()));
        } else if (flag.equalsIgnoreCase("setActorCmd")) {
            _setActorCmd.put(msg);
        }


//        logger.info(String.format("appDriver onmessage: %s, %s", channel, msg));
//        if (appMgr.getSensorsName().contains(channel)) {
//            if (!getSensorDataFlag.containsKey(channel)) {
//                getSensorDataFlag.put(channel, false);
//            }
//            if (getMsgThreadState && !getSensorDataFlag.get(channel)) {
//                //TODO: udp通信触发
//
//            } else {
//                //getSensorData
//                if (!sensorValues.containsKey(channel)) {
//                    sensorValues.put(channel, new SynchronousSensorData(1));
//                }
//                sensorValues.get(channel).put(SensorData.fromJSONString(msg));
//                getSensorDataFlag.put(channel, false);
//            }
//        } else {
//            //actorSetCmd
//            if (!actorSetState.containsKey(channel)) {
//                actorSetState.put(channel, new SynchronousSetState(1));
//            }
//            actorSetState.get(channel).put(SetState.fromString(msg));
//        }
    }

    @Override
    public void run() {
        String msgFromClient;
        while ((msgFromClient = tcp.recv()) != null) {
            JSONObject jo = JSON.parseObject(msgFromClient);
            if (appMgr != null) {
                logger.info(String.format("[%s -> Platform]: %s", appMgr.getAppName(), msgFromClient));
            } else {
                logger.info(String.format("[AppDriver -> Platform]: %s", msgFromClient));
            }

            String api = jo.getString("api");
            String ret = null;
            try {
                if (api == null) {

                } else if (api.equalsIgnoreCase("connect")) {
                    ret = connectPlatform();
                } else if (api.equalsIgnoreCase("disconnect")) {
                    ret = disConnectPlatform();
                } else if (api.equalsIgnoreCase("is_connected")) {
                    ret = checkConnect();
                } else if (api.equalsIgnoreCase("register_app")) {
                    String appName = jo.getString("app_name");
                    ret = registerApp(appName);
                } else if (api.equalsIgnoreCase("unregister_app")) {
                    String appName = jo.getString("app_name");
                    ret = unregisterApp(appName);
                } else if (api.equalsIgnoreCase("get_supported_sensors")) {
                    ret = getSupportedSensors();
                } else if (api.equalsIgnoreCase("get_registered_sensors")) {
                    String appName = jo.getString("app_name");
                    ret = getRegisteredSensors(appName);
                } else if (api.equalsIgnoreCase("get_registered_sensors_status")) {
                    String appName = jo.getString("app_name");
                    ret = getRegisteredSensorsStatus(appName);
                } else if (api.equalsIgnoreCase("register_sensor")) {
                    String sensorName = jo.getString("sensor_name");
                    SensorMode mode = SensorMode.fromString(jo.getString("mode"));
                    int freq = jo.getIntValue("freq");
                    String appName = jo.getString("app_name");
                    ret = registerSensor(appName, sensorName, mode, freq);
                } else if (api.equalsIgnoreCase("cancel_sensor")) {
                    String sensorName = jo.getString("sensor_name");
                    String appName = jo.getString("app_name");
                    ret = cancelSensor(appName, sensorName);
                } else if (api.equalsIgnoreCase("cancel_all_sensors")) {
                    String appName = jo.getString("app_name");
                    ret = cancelAllSensors(appName);
                } else if (api.equalsIgnoreCase("get_sensor_data")) {
                    String sensorName = jo.getString("sensor_name");
                    String appName = jo.getString("app_name");
                    ret = getSensorData(appName, sensorName);
                } else if (api.equalsIgnoreCase("get_all_sensor_data")) {
                    String appName = jo.getString("app_name");
                    ret = getAllSensorData(appName);
                } else if (api.equalsIgnoreCase("get_msg_thread")) {
                    CmdType cmd = CmdType.fromString(jo.getString("cmd"));
                    String appName = jo.getString("app_name");
                    ret = getMsgThread(appName, cmd);
                }else if (api.equalsIgnoreCase("get_supported_actors")) {
                    ret = getSupportedActors();
                } else if (api.equalsIgnoreCase("get_registered_actors")) {
                    String appName = jo.getString("app_name");
                    ret = getRegisteredActors(appName);
                } else if (api.equalsIgnoreCase("get_registered_actors_status")) {
                    String appName = jo.getString("app_name");
                    ret = getRegisteredActorsStatus(appName);
                } else if (api.equalsIgnoreCase("register_actor")) {
                    String actorName = jo.getString("actor_name");
                    String appName = jo.getString("app_name");
                    ret =  registerActor(appName, actorName);
                } else if (api.equalsIgnoreCase("cancel_actor")) {
                    String actorName = jo.getString("actor_name");
                    String appName = jo.getString("app_name");
                    ret = cancelActor(appName, actorName);
                } else if (api.equalsIgnoreCase("cancel_all_actors")) {
                    String appName = jo.getString("app_name");
                    ret = cancelAllActors(appName);
                } else if (api.equalsIgnoreCase("set_actor_cmd")) {
                    String actorName = jo.getString("actor_name");
                    String action = jo.getString("action");
                    String appName = jo.getString("app_name");
                    ret = setActorCmd(appName, actorName, action);
                } else if (api.equalsIgnoreCase("is_service_on")) {
                    ServiceType service = ServiceType.fromString(jo.getString("service_type"));
                    String appName = jo.getString("app_name");
                    ret = isServiceOn(appName, service);
                } else if (api.equalsIgnoreCase("start_service")) {
                    ServiceType service = ServiceType.fromString(jo.getString("service_type"));
                    ServiceConfig config = null;
                    try {
                        if (service == ServiceType.CTX) {
                            config = CtxServiceConfig.fromJSONString(jo.getString("config"));
                        } else {
                            config = InvServiceConfig.fromJSONString(jo.getString("config"));
                        }
                    } catch (Exception ignored) {}
                    String appName = jo.getString("app_name");
                    ret = serviceCall(appName, service, CmdType.START, config);
                } else if (api.equalsIgnoreCase("stop_service")) {
                    ServiceType service = ServiceType.fromString(jo.getString("service_type"));
                    String appName = jo.getString("app_name");
                    ret = serviceCall(appName, service, CmdType.STOP, null);
                } else if (api.equalsIgnoreCase("service_call")) {
                    ServiceType service = ServiceType.fromString(jo.getString("service_type"));
                    CmdType cmd = CmdType.fromString(jo.getString("cmd_type"));
                    ServiceConfig config = null;
                    try {
                        if (service == ServiceType.CTX) {
                            config = CtxServiceConfig.fromJSONString(jo.getString("config"));
                        } else {
                            config = InvServiceConfig.fromJSONString(jo.getString("config"));
                        }
                    } catch (Exception ignored) {}
                    String appName = jo.getString("app_name");
                    ret = serviceCall(appName, service, cmd, config);
                } else if (api.equalsIgnoreCase("get_sensor_info")) {
                    String sensorName = jo.getString("sensor_name");
                    ret = getSensorInfo(sensorName);
                } else if (api.equalsIgnoreCase("get_sensor_info_and_data")) {
                    String sensorName = jo.getString("sensor_name");
                    ret = getSensorInfoAndData(sensorName);
                } else if (api.equalsIgnoreCase("get_all_sensor_info")) {
                    ret = getSupportedSensors();
                } else if (api.equalsIgnoreCase("get_all_sensor_info_and_data")) {
                    ret = getAllSensorInfoAndData();
                } else if (api.equalsIgnoreCase("get_actor_info")) {
                    String actorName = jo.getString("actor_name");
                    ret = getActorInfo(actorName);
                } else if (api.equalsIgnoreCase("get_all_actor_info")) {
                    ret = getSupportedActors();
                } else if (api.equalsIgnoreCase("get_app_info")) {
                    String appName = jo.getString("app_name");
                    ret = getAppInfo(appName);
                } else if (api.equalsIgnoreCase("get_all_app_info")) {
                    ret = getAllAppInfo();
                } else if (api.equalsIgnoreCase("get_service_info")) {
                    String appName = jo.getString("app_name");
                    ServiceType service = ServiceType.fromString(jo.getString("service_type"));
                    ret = getServiceInfo(appName, service);
                } else if (api.equalsIgnoreCase("get_all_service_info")) {
                    ServiceType service = ServiceType.fromString(jo.getString("service_type"));
                    ret = getAllServiceInfo(service);
                } else if (api.equalsIgnoreCase("db_create")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    String primaryKey = jo.getString("primary_key");
                    int rowLimit = jo.getIntValue("row_limit");
                    List<String> header = jo.getJSONArray("header").toJavaList(String.class);
                    ret = dbCreate(appName, tableName, primaryKey, header, rowLimit);
                } else if (api.equalsIgnoreCase("db_drop")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    ret = dbDrop(appName, tableName);
                } else if (api.equalsIgnoreCase("db_insert")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    JSONObject rowJson = jo.getJSONObject("row");
                    Map<String, Object> row = new LinkedHashMap<>(rowJson);
                    ret = dbInsert(appName, tableName, row);
                } else if (api.equalsIgnoreCase("db_inserts")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    JSONArray rowsJson = jo.getJSONArray("rows");
                    ret = "{\"state\": false}";
                    if (rowsJson != null) {
                        int i;
                        for (i = 0; i < rowsJson.size(); i++) {
                            if (dbInsert(appName, tableName, new LinkedHashMap<>(rowsJson.getJSONObject(i))).equalsIgnoreCase("{\"state\": false}")) {
                                break;
                            }
                        }
                        if (i == rowsJson.size()) {
                            ret = "{\"state\": true}";
                        }
                    }
                } else if (api.equalsIgnoreCase("db_update")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    JSONObject rowJson = jo.getJSONObject("row");
                    Map<String, Object> row = new LinkedHashMap<>(rowJson);
                    ret = dbUpdate(appName, tableName, row);
                } else if (api.equalsIgnoreCase("db_delete")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    int row = jo.getIntValue("row");
                    JSONArray conditionsJson = jo.getJSONArray("conditions");
                    List<Condition> conditions;
                    if (conditionsJson == null) {
                        conditions = null;
                    } else {
                        conditions = new ArrayList<>();
                        for (int i = 0; i < conditionsJson.size(); i++) {
                            conditions.add(new Condition(conditionsJson.getJSONObject(i)));
                        }
                    }
                    JSONArray ordersJson = jo.getJSONArray("orders");
                    List<Order> orders;
                    if (ordersJson == null) {
                        orders = null;
                    } else {
                        orders = new ArrayList<>();
                        for (int i = 0; i < ordersJson.size(); i++) {
                            orders.add(new Order(ordersJson.getJSONObject(i)));
                        }
                    }
                    ret = dbDelete(appName, tableName, row, conditions, orders);
                } else if (api.equalsIgnoreCase("db_deletes")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    int rows = jo.getIntValue("rows");
                    JSONArray conditionsJson = jo.getJSONArray("conditions");
                    List<Condition> conditions;
                    if (conditionsJson == null) {
                        conditions = null;
                    } else {
                        conditions = new ArrayList<>();
                        for (int i = 0; i < conditionsJson.size(); i++) {
                            conditions.add(new Condition(conditionsJson.getJSONObject(i)));
                        }
                    }
                    JSONArray ordersJson = jo.getJSONArray("orders");
                    List<Order> orders;
                    if (ordersJson == null) {
                        orders = null;
                    } else {
                        orders = new ArrayList<>();
                        for (int i = 0; i < ordersJson.size(); i++) {
                            orders.add(new Order(ordersJson.getJSONObject(i)));
                        }
                    }
                    ret = dbDeletes(appName, tableName, rows, conditions, orders);
                } else if (api.equalsIgnoreCase("db_row")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    int row = jo.getIntValue("row");
                    JSONArray columnsJson = jo.getJSONArray("columns");
                    List<String> columns;
                    if (columnsJson == null) {
                        columns = null;
                    } else {
                        columns = new ArrayList<>();
                        for (int i = 0; i < columnsJson.size(); i++) {
                            columns.add(columnsJson.getString(i));
                        }
                    }
                    JSONArray conditionsJson = jo.getJSONArray("conditions");
                    List<Condition> conditions;
                    if (conditionsJson == null) {
                        conditions = null;
                    } else {
                        conditions = new ArrayList<>();
                        for (int i = 0; i < conditionsJson.size(); i++) {
                            conditions.add(new Condition(conditionsJson.getJSONObject(i)));
                        }
                    }
                    JSONArray ordersJson = jo.getJSONArray("orders");
                    List<Order> orders;
                    if (ordersJson == null) {
                        orders = null;
                    } else {
                        orders = new ArrayList<>();
                        for (int i = 0; i < ordersJson.size(); i++) {
                            orders.add(new Order(ordersJson.getJSONObject(i)));
                        }
                    }
                    ret = dbRow(appName, tableName, row, columns, conditions, orders);
                } else if (api.equalsIgnoreCase("db_rows")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    int rows = jo.getIntValue("rows");
                    JSONArray columnsJson = jo.getJSONArray("columns");
                    List<String> columns;
                    if (columnsJson == null) {
                        columns = null;
                    } else {
                        columns = new ArrayList<>();
                        for (int i = 0; i < columnsJson.size(); i++) {
                            columns.add(columnsJson.getString(i));
                        }
                    }
                    JSONArray conditionsJson = jo.getJSONArray("conditions");
                    List<Condition> conditions;
                    if (conditionsJson == null) {
                        conditions = null;
                    } else {
                        conditions = new ArrayList<>();
                        for (int i = 0; i < conditionsJson.size(); i++) {
                            conditions.add(new Condition(conditionsJson.getJSONObject(i)));
                        }
                    }
                    JSONArray ordersJson = jo.getJSONArray("orders");
                    List<Order> orders;
                    if (ordersJson == null) {
                        orders = null;
                    } else {
                        orders = new ArrayList<>();
                        for (int i = 0; i < ordersJson.size(); i++) {
                            orders.add(new Order(ordersJson.getJSONObject(i)));
                        }
                    }
                    ret = dbRows(appName, tableName, rows, columns, conditions, orders);
                } else if (api.equalsIgnoreCase("db_column")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    int rows = jo.getIntValue("rows");
                    String column = jo.getString("column");
                    JSONArray conditionsJson = jo.getJSONArray("conditions");
                    List<Condition> conditions;
                    if (conditionsJson == null) {
                        conditions = null;
                    } else {
                        conditions = new ArrayList<>();
                        for (int i = 0; i < conditionsJson.size(); i++) {
                            conditions.add(new Condition(conditionsJson.getJSONObject(i)));
                        }
                    }
                    JSONArray ordersJson = jo.getJSONArray("orders");
                    List<Order> orders;
                    if (ordersJson == null) {
                        orders = null;
                    } else {
                        orders = new ArrayList<>();
                        for (int i = 0; i < ordersJson.size(); i++) {
                            orders.add(new Order(ordersJson.getJSONObject(i)));
                        }
                    }
                    ret = dbColumn(appName, tableName, rows, column, conditions, orders);
                } else if (api.equalsIgnoreCase("db_columns")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    int rows = jo.getIntValue("rows");
                    JSONArray columnsJson = jo.getJSONArray("columns");
                    List<String> columns;
                    if (columnsJson == null) {
                        columns = null;
                    } else {
                        columns = new ArrayList<>();
                        for (int i = 0; i < columnsJson.size(); i++) {
                            columns.add(columnsJson.getString(i));
                        }
                    }
                    JSONArray conditionsJson = jo.getJSONArray("conditions");
                    List<Condition> conditions;
                    if (conditionsJson == null) {
                        conditions = null;
                    } else {
                        conditions = new ArrayList<>();
                        for (int i = 0; i < conditionsJson.size(); i++) {
                            conditions.add(new Condition(conditionsJson.getJSONObject(i)));
                        }
                    }
                    JSONArray ordersJson = jo.getJSONArray("orders");
                    List<Order> orders;
                    if (ordersJson == null) {
                        orders = null;
                    } else {
                        orders = new ArrayList<>();
                        for (int i = 0; i < ordersJson.size(); i++) {
                            orders.add(new Order(ordersJson.getJSONObject(i)));
                        }
                    }
                    ret = dbColumns(appName, tableName, rows, columns, conditions, orders);
                } else if (api.equalsIgnoreCase("db_cell")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    int row = jo.getIntValue("row");
                    String column = jo.getString("column");
                    JSONArray conditionsJson = jo.getJSONArray("conditions");
                    List<Condition> conditions;
                    if (conditionsJson == null) {
                        conditions = null;
                    } else {
                        conditions = new ArrayList<>();
                        for (int i = 0; i < conditionsJson.size(); i++) {
                            conditions.add(new Condition(conditionsJson.getJSONObject(i)));
                        }
                    }
                    JSONArray ordersJson = jo.getJSONArray("orders");
                    List<Order> orders;
                    if (ordersJson == null) {
                        orders = null;
                    } else {
                        orders = new ArrayList<>();
                        for (int i = 0; i < ordersJson.size(); i++) {
                            orders.add(new Order(ordersJson.getJSONObject(i)));
                        }
                    }
                    ret = dbCell(appName, tableName, row, column, conditions, orders);
                } else if (api.equalsIgnoreCase("db_header")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    ret = dbHeader(appName, tableName);
                } else if (api.equalsIgnoreCase("db_count")) {
                    String appName = jo.getString("app_name");
                    String tableName = jo.getString("table_name");
                    ret = dbCount(appName, tableName);
                } else if (api.equalsIgnoreCase("inv_monitor")) {
                    ret = monitor(jo.getString("app_name"), jo.getJSONArray("objs"));
                } else if (api.equalsIgnoreCase("inv_is_monitored")) {
                    ret = isMonitored(jo.getString("app_name"), jo.getJSONArray("objs"));
                } else if (api.equalsIgnoreCase("inv_check")) {
                    ret = check(jo.getString("app_name"), jo);
                } else if (api.equalsIgnoreCase("inv_save")) {
                    ret = save(jo.getString("app_name"));
                } else if (api.equalsIgnoreCase("inv_load")) {
                    ret = load(jo.getString("app_name"), jo.getString("content"));
                } else if (api.equalsIgnoreCase("inv_check_generated")) {
                    ret = checkGenerated(jo.getString("app_name"));
                }
            } catch (Exception e) {
                logger.error(msgFromClient + " -> " + e.getMessage());
            }
            tcp.send(ret);
            if (appMgr != null) {
                logger.info(String.format("[Platform -> %s]: %s", appMgr.getAppName(), ret));
            } else {
                logger.info(String.format("[Platform -> AppDriver]: %s", ret));
            }
            if (api.equalsIgnoreCase("disconnect")) {
                break;
            }
        }
        tcp.close();
    }

    private String connectPlatform() {
//        grpId = AppMgrThread.getNewGrpId();
        JSONObject retJson = new JSONObject(1);
        retJson.put("state", true);
//        logger.info("clientIP: " + clientIP + ", clientUDPPort: " + clientUDPPort + ", grpId: " + grpId);
        return retJson.toJSONString();
    }

    private String disConnectPlatform() {
        String ret = "{\"state\":true}";
        if (appMgr != null) {
            ret = unregisterApp(appMgr.getAppName());
        }
//        AppMgrThread.removeGrpId(grpId);
//        grpId = -1;
        return ret;
    }

    private String checkConnect() {
        JSONObject retJson = new JSONObject(1);
        if (appMgr != null) {
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    private String registerApp(String appName) {
        JSONObject retJson = new JSONObject(2);
        if (appMgr == null) {
            clientIP = tcp.getSocket().getInetAddress().getHostAddress();
            clientUDPPort = AppMgrThread.getNewPort(tcp.getSocket());
            grpId = AppMgrThread.getNewGrpId(appName);
            appMgr = new AppMgr(appName);
            appMgr.setGrpId(grpId);
            appMgr.setAppDriver(this);
            AppMgrThread.getAppMgrs().put(appName, appMgr);
            retJson.put("state", true);
            retJson.put("udp_port", clientUDPPort);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    private String unregisterApp(String appName) {
        JSONObject retJson = new JSONObject(1);
        if (appMgr != null && appMgr.getAppName().equalsIgnoreCase(appName)) {
            cancelAllSensors(appName);
            cancelAllActors(appName);
            AppMgrThread.getAppMgrs().remove(appName);
            appMgr.removeDatabase();
            appMgr = null;
            AppMgrThread.removePort(tcp.getSocket(), clientUDPPort);
            clientIP = null;
            clientUDPPort = -1;
            getMsgThreadState = false;
            //TODO:还有剩余资源待释放
            serviceCall(appName, ServiceType.ALL, CmdType.STOP, null);
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
//        logger.info("\n" + appName + " exit!");
//        logger.info("sensors:");
//        sensorMgrMap.forEach((s, config) -> {
//            logger.info(s + " -> " + config.getAppsName());
//        });
//        logger.info("actors:");
//        actorMgrMap.forEach((s, config) -> {
//            logger.info(s + " -> " + config.getAppsName());
//        });
//        logger.info("appNames:");
//        appMgrMap.forEach((s, config) -> {
//            logger.info(s + " -> sensors:" + config.getSensorsName() + ", actors:" + config.getActorsName());
//        });
        return retJson.toJSONString();
    }

    private String getSupportedSensors() {
        JSONArray retJsonArray = new JSONArray();
        ResMgrThread.getSensorMgrs().forEach((sensorName, config) -> {
            retJsonArray.add(JSONObject.parse(config.toString()));
        });
        return retJsonArray.toJSONString();
    }

    private String getRegisteredSensors(String appName) {
        JSONArray retJsonArray = new JSONArray();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            appMgr.getSensors().forEach(config -> {
                retJsonArray.add(JSONObject.parse(config.toString()));
            });
        }
        return retJsonArray.toJSONString();
    }

    private String getRegisteredSensorsStatus(String appName) {
        JSONObject retJson = new JSONObject(1);
        boolean status = true;
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            for (SensorMgr config : appMgr.getSensors()) {
                if (!config.isAlive()) {
                    status = false;
                    break;
                }
            }
        } else {
            status = false;
        }
        retJson.put("state", status);
        return retJson.toJSONString();
    }

    private void _registerSensor(String appName, String sensorName, SensorMode mode, int freq) {
        SensorMgr sensorMgr = ResMgrThread.getSensorMgrs().get(sensorName);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if(appMgr.addSensor(sensorMgr)){
            sensorMgr.getApps().add(appMgr);
            subscribe(Channel.getSensor(sensorName), grpId);
        }

//        if (sensorMgr.getTimeLine().size() != 0) {
//            sensorMgr.getTimeLineLock().lock();
//        }
        synchronized (sensorMgr.getTimeLine()) {
            if (mode == SensorMode.ACTIVE) {
                sensorMgr.getTimeLine().deleteAppName(appMgr.getAppName(), freq);
            } else {
                sensorMgr.getTimeLine().insertAppName(appMgr.getAppName(), freq);
            }
            if (sensorMgr.getTimeLine().size() != 0) {
                sensorMgr.getTimeLine().notify();
//                logger.info(sensorMgr.getTimeLine());
            }
        }

//        if (sensorMgr.getTimeLine().size() != 0) {
//            sensorMgr.getTimeLineLock().unlock();
//        }
    }

    private String registerSensor(String appName, String sensorName, SensorMode mode, int freq) {
        JSONObject retJson = new JSONObject(1);
        Map<String, SensorMgr> sensorMgrMap = ResMgrThread.getSensorMgrs();
        SensorMgr sensorMgr = sensorMgrMap.get(sensorName);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null
                && sensorMgrMap.containsKey(sensorName)
                && ((mode == SensorMode.ACTIVE && freq == -1) ||
                (mode == SensorMode.PASSIVE && sensorMgr.checkValueFreq(freq)))) {
            _registerSensor(appName, sensorName, mode, freq);
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    public void _cancelSensor(String appName, String sensorName) {
        SensorMgr sensorMgr = ResMgrThread.getSensorMgrs().get(sensorName);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if(appMgr.removeSensor(sensorMgr)){
            sensorMgr.getApps().remove(appMgr);
            if (sensorMgr.getApps().size() == 0) {
                //TODO:可能有死锁
                sensorMgr.stopGetValue();
            }
            unsubscribe(Channel.getSensor(sensorName));
        }

//        if (sensorMgr.getTimeLine().size() != 0) {
//            sensorMgr.getTimeLineLock().lock();
//        }
        synchronized (sensorMgr.getTimeLine()) {
            if (sensorMgr.getTimeLine().getAppName2Freq().containsKey(appMgr.getAppName())) {
                int freq = sensorMgr.getTimeLine().getAppName2Freq().get(appMgr.getAppName());
                sensorMgr.getTimeLine().deleteAppName(appMgr.getAppName(), freq);
                sensorMgr.getTimeLine().getAppName2Freq().remove(appMgr.getAppName());
            }
//            if (sensorMgr.getTimeLine().size() != 0) {
//                logger.info(sensorMgr.getTimeLine());
//            }
        }

//        if (sensorMgr.getTimeLine().size() != 0) {
//            sensorMgr.getTimeLineLock().unlock();
//        }
    }

    private String cancelSensor(String appName, String sensorName) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null && appMgr.getSensorsName().contains(sensorName)) {
            _cancelSensor(appName, sensorName);
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    private String cancelAllSensors(String appName) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            appMgr.getSensorsName().forEach(sensorName -> {
                cancelSensor(appName, sensorName);
            });
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    private String getSensorData(String appName, String sensorName) {
        String value = "{\"default\":\"@#$%\"}";
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null && appMgr.getAppName().equals("WebServer") && !appMgr.getSensorsName().contains(sensorName)) {
            registerSensor(appName, sensorName, SensorMode.ACTIVE, -1);
        }
        if (appMgr != null
                && appMgr.getSensorsName().contains(sensorName)
                && ResMgrThread.getSensorMgrs().get(sensorName).isAlive()) {
            CmdMessageGrpIds send = new CmdMessageGrpIds("sensory_request", null, List.of(grpId));
            if (!appMgr.getRequestMap().containsKey(Channel.getSensor(sensorName))) {
                appMgr.getRequestMap().put(Channel.getSensor(sensorName), new SynchronousString());
            }
            appMgr.getRequestMap().get(Channel.getSensor(sensorName)).put("getSensorData");
            Publisher.publish(Channel.getSensorRequest(sensorName), send.toString());
            value = _getSensorData.blockTake();
//            Cmd cmd = new Cmd("sensor_get", sensorName + " " + grpId);
//            PlatformUDP.send(cmd);
//            getSensorDataFlag.put(sensorName, true);
//            if (!sensorValues.containsKey(sensorName)) {
//                sensorValues.put(sensorName, new SynchronousSensorData(1));
//            }
//            value = sensorValues.get(sensorName).blockTake().toString();
        }
        return value;
    }

    private String getAllSensorData(String appName) {
        JSONArray ja = new JSONArray();
        if (appName.equals("WebServer")) {
            ResMgrThread.getSensorMgrs().forEach((sensorName, sensorMgr) -> {
                JSONObject joo = new JSONObject(2);
                joo.put("sensor_name", sensorName);
                joo.put("value", getSensorData(appName, sensorName));
                ja.add(joo);
            });
        } else {
            AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
            appMgr.getSensorsName().forEach(sensorName -> {
                JSONObject joo = new JSONObject(2);
                joo.put("sensor_name", sensorName);
                joo.put("value", getSensorData(appName, sensorName));
                ja.add(joo);
            });
        }
        return ja.toJSONString();
    }

    private String getMsgThread(String appName, CmdType cmd) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (cmd == CmdType.START) {
            getMsgThreadState = true;
            appMgr.getSensors().forEach(sensorMgr -> {
                if (!sensorMgr.isGetValueRunning()) {
                    sensorMgr.startGetValue();
                }
            });
        } else if (cmd == CmdType.STOP) {
            getMsgThreadState = false;
            appMgr.getSensors().forEach(sensorMgr -> {
                if (sensorMgr.isGetValueRunning() && sensorMgr.getApps().size() == 1 && sensorMgr.getApps().contains(appMgr)) {
                    sensorMgr.stopGetValue();
                }
            });
        }
        retJson.put("state", true);
        return retJson.toJSONString();
    }
    
    private String getSupportedActors() {
        JSONArray retJsonArray = new JSONArray();
        ResMgrThread.getActorMgrs().forEach((actorName, config) -> {
            retJsonArray.add(JSONObject.parse(config.toString()));
        });
        return retJsonArray.toJSONString();
    }

    private String getRegisteredActors(String appName) {
        JSONArray retJsonArray = new JSONArray();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            appMgr.getActors().forEach(config -> {
                retJsonArray.add(JSONObject.parse(config.toString()));
            });
        }
        return retJsonArray.toJSONString();
    }

    private String getRegisteredActorsStatus(String appName) {
        JSONObject retJson = new JSONObject(1);
        boolean state = true;
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            for (ActorMgr config : appMgr.getActors()) {
                if (!config.isAlive()) {
                    state = false;
                    break;
                }
            }
        } else {
            state = false;
        }

        retJson.put("state", state);
        return retJson.toJSONString();
    }

    private String registerActor(String appName, String actorName) {
        JSONObject retJson = new JSONObject(1);
        Map<String, ActorMgr> actorMgrMap = ResMgrThread.getActorMgrs();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null && actorMgrMap.containsKey(actorName)) {
            ActorMgr actorMgr = actorMgrMap.get(actorName);
            appMgr.getActors().add(actorMgr);
            actorMgr.getApps().add(appMgr);
            subscribe(Channel.getActor(actorName), grpId);
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    private String cancelActor(String appName, String actorName) {
        JSONObject retJson = new JSONObject(1);
        Map<String, ActorMgr> actorMgrMap = ResMgrThread.getActorMgrs();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null && appMgr.getActorsName().contains(actorName)) {
            ActorMgr actorMgr = actorMgrMap.get(actorName);
            appMgr.getActors().remove(actorMgr);
            actorMgr.getApps().remove(appMgr);
            unsubscribe(Channel.getActor(actorName));
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    private String cancelAllActors(String appName) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        appMgr.getActorsName().forEach(actorName ->{
            cancelActor(appName, actorName);
        });
        retJson.put("state", true);
        return retJson.toJSONString();
    }

//    private String setActorCmd(String actorName, String... args) {
//        JSONObject retJson = new JSONObject(1);
//        Map<String, ActorMgr> actorMgrMap = ResMgrThread.getActorMgrs();
//        if (appMgr != null
//                && appMgr.getActorsName().contains(actorName)
//                && actorMgrMap.get(actorName).isAlive()) {
//            PlatformUDP.send(new Cmd("actor_set", String.join(" ", args)));
//            retJson.put("state", true);
//        } else {
//            retJson.put("state", false);
//        }
//        return retJson.toJSONString();
//    }

    private String setActorCmd(String appName, String actorName, String action) {
        JSONObject retJson = new JSONObject(1);
        Map<String, ActorMgr> actorMgrMap = ResMgrThread.getActorMgrs();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null
                && appMgr.getActorsName().contains(actorName)
                && actorMgrMap.get(actorName).isAlive()) {
//            PlatformUDP.send(new Cmd("actor_set", actorName + " " + grpId + " " + action));
//            boolean state = actorSetState.get(actorName).blockTake().get();
            CmdMessageGrpIds send = new CmdMessageGrpIds("action_request", action, List.of(grpId));
            if (!appMgr.getRequestMap().containsKey(Channel.getActor(actorName))) {
                appMgr.getRequestMap().put(Channel.getActor(actorName), new SynchronousString());
            }
            appMgr.getRequestMap().get(Channel.getActor(actorName)).put("setActorCmd");
            Publisher.publish(Channel.getActorRequest(actorName), send.toString());
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    private String isServiceOn(String appName, ServiceType service) {
        boolean state = false;
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            switch (service) {
                case CTX:
                    state = appMgr.isCtxServerOn();
                    break;
                case INV:
                    state = appMgr.isInvServerOn();
                    break;
                case ALL:
                    state = appMgr.isCtxServerOn() && appMgr.isInvServerOn();
                    break;
            }
        }
        return "{\"state\":" + state + "}";
    }

    private String serviceCall(String appName, ServiceType service, CmdType cmd, ServiceConfig config) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr == null) {
            retJson.put("state", false);
        } else {
            boolean ret = Platform.call(appMgr.getAppName(), service, cmd, config);
            retJson.put("state", ret);
        }
        return retJson.toJSONString();
    }

    public String getSensorInfo(String sensorName) {
        String ret = "";
        try {
            ret = ResMgrThread.getSensorMgrs().get(sensorName).toString();
        } catch (Exception ignored) {}
        return ret;
    }

    public String getSensorInfoAndData(String sensorName) {
        String ret = "";
        try {
            SensorInfo sensorInfo = ResMgrThread.getSensorMgrs().get(sensorName).getSensorInfo();
            System.out.println("here");
            String sensorData = getSensorData(appMgr.getAppName(), sensorName);
            System.out.println("here1");
            JSONObject jo = sensorInfo.toJSONObject();
            jo.put("value", sensorData);
            System.out.println("here3");
            ret = jo.toJSONString();
        } catch (Exception ignored) {}
        return ret;
    }

    public String getAllSensorInfoAndData() {
        JSONArray ja = new JSONArray();
        ResMgrThread.getSensorMgrs().forEach((sensorName, config) -> {
            String sensorData = getSensorData(appMgr.getAppName(), sensorName);
            JSONObject jo = config.getSensorInfo().toJSONObject();
            jo.put("value", sensorData);
            ja.add(jo);
        });
        return ja.toJSONString();
    }

    public String getActorInfo(String actorName) {
        String ret = "";
        try {
            ret = ResMgrThread.getActorMgrs().get(actorName).toString();
        } catch (Exception ignored) {}
        return ret;
    }

    public String getAppInfo(String appName) {
        String ret = "";
        try {
            ret = AppMgrThread.getAppMgrs().get(appName).toString();
        } catch (Exception ignored) {}
        return ret;
    }

    public String getAllAppInfo() {
        JSONArray ja = new JSONArray();
        AppMgrThread.getAppMgrs().forEach((appName, config) -> {
            if (!appName.equals("WebServer")) {
                ja.add(JSONObject.parse(config.toString()));
            }
        });
        return ja.toJSONString();
    }

    public String getServiceInfo(String appName, ServiceType service) {
        ServiceInfo ret;
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            ret = appMgr.getServiceInfo(service);
            return ret.toString();
        }
        return "{\"service_type\":\"" + service + "\",\"app_name\":\"" + appName + "\",\"state\":\"off\"}";
    }

    public String getAllServiceInfo(ServiceType service) {
        JSONArray ja = new JSONArray();
        AppMgrThread.getAppMgrs().forEach((appName, config) -> {
            if (!appName.equals("WebServer")) {
                ja.add(config.getServiceInfo(service).toJSONObject());
            }
        });
        return ja.toJSONString();
    }

    public String dbCreate(String appName, String tableName, String primaryKey, List<String> header, int rowLimit) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            retJson.put("state", appMgr.getDatabase().dbCreate(tableName, primaryKey, header, rowLimit));
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    public String dbDrop(String appName, String tableName) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            retJson.put("state", appMgr.getDatabase().dbDrop(tableName));
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    public String dbInsert(String appName, String tableName, Map<String, Object> row) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            retJson.put("state", appMgr.getDatabase().dbInsert(tableName, row));
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    public String dbUpdate(String appName, String tableName, Map<String, Object> row) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            retJson.put("state", appMgr.getDatabase().dbUpdate(tableName, row));
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    public String dbDelete(String appName, String tableName, int row, List<Condition> conditions
            , List<Order> orders) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null && appMgr.getDatabase().dbDelete(tableName, row, conditions, orders)) {
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    public String dbDeletes(String appName, String tableName, int rows, List<Condition> conditions
            , List<Order> orders) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null && appMgr.getDatabase().dbDeletes(tableName, rows, conditions, orders)) {
            retJson.put("state", true);
        } else {
            retJson.put("state", false);
        }
        return retJson.toJSONString();
    }

    public String dbRow(String appName, String tableName, int row, List<String> columns, List<Condition> conditions
            , List<Order> orders) {
        JSONObject retJson = new JSONObject();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            retJson.putAll(appMgr.getDatabase().dbRow(tableName, row, columns, conditions, orders));
        }
        return retJson.toJSONString();
    }

    public String dbRows(String appName, String tableName, int rows, List<String> columns, List<Condition> conditions
            , List<Order> orders) {
        JSONArray retJsonArray = new JSONArray();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            appMgr.getDatabase().dbRows(tableName, rows, columns, conditions, orders).forEach(row -> {
                JSONObject jo = new JSONObject();
                jo.putAll(row);
                retJsonArray.add(jo);
            });
        }
        return retJsonArray.toJSONString();
    }

    public String dbColumn(String appName, String tableName, int rows, String column,
                           List<Condition> conditions, List<Order> orders) {
        JSONArray retJsonArray = new JSONArray();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            retJsonArray.addAll(appMgr.getDatabase().dbColumn(tableName, rows, column, conditions, orders));
        }
        return retJsonArray.toJSONString();
    }

    public String dbColumns(String appName, String tableName, int rows, List<String> columns,
                           List<Condition> conditions, List<Order> orders) {
        JSONObject retJson = new JSONObject();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            appMgr.getDatabase().dbColumns(tableName, rows, columns, conditions, orders).forEach((column, values) -> {
                JSONArray ja = new JSONArray();
                ja.addAll(values);
                retJson.put(column, ja);
            });
        }
        return retJson.toJSONString();
    }

    public String dbCell(String appName, String tableName, int row, String column,
                         List<Condition> conditions, List<Order> orders) {
        String ret = "@#$%";
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            ret = appMgr.getDatabase().dbCell(tableName, row, column, conditions, orders).toString();
        }
        return ret;
    }

    public String dbHeader(String appName, String tableName) {
        JSONArray retJsonArray = new JSONArray();
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            retJsonArray.addAll(appMgr.getDatabase().dbHeader(tableName));
        }
        return retJsonArray.toJSONString();
    }

    public String dbCount(String appName, String tableName) {
        JSONObject retJson = new JSONObject(1);
        AppMgr appMgr = AppMgrThread.getAppMgrs().get(appName);
        if (appMgr != null) {
            retJson.put("size", appMgr.getDatabase().dbCount(tableName));
        } else {
            retJson.put("size", -1);
        }
        return retJson.toJSONString();
    }

    private String monitor(String appName, JSONArray objs) {
        AppInvServer appInvServer = PlatformInvServer.getAppInvServer(appName);
        boolean ret = false;
        if (appInvServer != null) {
            ret = appInvServer.monitor(objs.toJavaList(String.class));
        }
        return "{\"state\":" + ret + "}";
    }

    private String isMonitored(String appName, JSONArray objs) {
        AppInvServer appInvServer = PlatformInvServer.getAppInvServer(appName);
        boolean ret = false;
        if (appInvServer != null) {
            ret = appInvServer.isMonitored(objs.toJavaList(String.class));
        }
        return "{\"state\":" + ret + "}";
    }

    private String check(String appName, JSONObject jo) {
        AppInvServer appInvServer = PlatformInvServer.getAppInvServer(appName);
        boolean ret = false;
        if (appInvServer != null) {
            ret = appInvServer.check(jo);
        }
        return "{\"state\":" + ret + "}";
    }

    private String save(String appName) {
        AppInvServer appInvServer = PlatformInvServer.getAppInvServer(appName);
        if (appInvServer != null) {
            JSONObject retJson = new JSONObject(1);
            retJson.put("content", appInvServer.save());
            return retJson.toJSONString();
        } else {
            return "{\"content\":\"@#$%\"}";
        }
    }

    private String load(String appName, String content) {
        try {
            AppInvServer appInvServer = PlatformInvServer.getAppInvServer(appName);
            if (appInvServer != null) {
                JSONObject retJson = new JSONObject(1);
                retJson.put("state", appInvServer.load(JSON.parseObject(content)));
                return retJson.toJSONString();
            } else {
                return "{\"state\":false}";
            }
        } catch (Exception e) {
            return "{\"state\":false}";
        }
    }

    private String checkGenerated(String appName) {
        AppInvServer appInvServer = PlatformInvServer.getAppInvServer(appName);
        if (appInvServer != null) {
            JSONObject retJson = new JSONObject(1);
            retJson.put("state", appInvServer.checkGenerated());
            return retJson.toJSONString();
        } else {
            return "{\"state\":false}";
        }
    }
}
